import 'package:mobx/mobx.dart';
import '../models/chat_model.dart';
import '../models/message_model.dart';
import '../services/chat_service.dart';
import '../services/user_service.dart';
import 'auth_store.dart';

part 'chat_store.g.dart';

class ChatStore = _ChatStore with _$ChatStore;

abstract class _ChatStore with Store {
  final ChatService _chatService = ChatService();
  final UserService _userService = UserService();
  final AuthStore _authStore;

  _ChatStore(this._authStore);

  @observable
  ObservableList<ChatModel> chats = ObservableList<ChatModel>();

  @observable
  ObservableMap<String, ObservableList<MessageModel>> chatMessages =
      ObservableMap<String, ObservableList<MessageModel>>();

  @observable
  ChatModel? currentChat;

  @observable
  bool isLoading = false;

  @observable
  String? errorMessage;

  @computed
  List<ChatModel> get groupChats {
    if (_authStore.currentUser == null) return [];
    return chats
        .where(
          (chat) =>
              chat.isGroupChat &&
              chat.participantIds.contains(_authStore.currentUser!.id),
        )
        .toList();
  }

  @computed
  List<ChatModel> get privateChats {
    if (_authStore.currentUser == null) return [];
    return chats
        .where(
          (chat) =>
              !chat.isGroupChat &&
              chat.participantIds.contains(_authStore.currentUser!.id),
        )
        .toList();
  }

  @action
  Future<void> loadUserChats() async {
    if (_authStore.currentUser == null) return;

    isLoading = true;
    errorMessage = null;

    try {
      final userChats = _chatService.getUserChats(_authStore.currentUser!.id);
      chats.clear();
      chats.addAll(userChats);
      isLoading = false;
    } catch (e) {
      errorMessage = 'Load chat list failed: ${e.toString()}';
      isLoading = false;
    }
  }

  @action
  Future<void> loadChatMessages(String chatId) async {
    isLoading = true;
    errorMessage = null;

    try {
      final messages = _chatService.getMessagesByChat(chatId);
      final observableMessages = ObservableList<MessageModel>.of(messages);
      chatMessages[chatId] = observableMessages;
      isLoading = false;
    } catch (e) {
      errorMessage = 'Load chat messages failed: ${e.toString()}';
      isLoading = false;
    }
  }

  @action
  Future<void> selectChat(String chatId) async {
    currentChat = _chatService.getChatById(chatId);

    // 加载消息
    if (currentChat != null) {
      await loadChatMessages(chatId);

      // 标记消息为已读
      if (_authStore.currentUser != null) {
        await markMessagesAsRead(chatId);
      }
    }
  }

  @action
  Future<MessageModel?> sendMessage(
    String chatId,
    String content, {
    bool isEmoji = false,
    String? emojiPath,
    bool isTeamInvite = false,
    String? teamId,
  }) async {
    if (_authStore.currentUser == null) return null;

    isLoading = true;
    errorMessage = null;

    try {
      final message = await _chatService.sendMessage(
        chatId: chatId,
        senderId: _authStore.currentUser!.id,
        content: content,
        isEmoji: isEmoji,
        emojiPath: emojiPath,
        isTeamInvite: isTeamInvite,
        teamId: teamId,
      );

      // 更新消息列表
      if (chatMessages.containsKey(chatId)) {
        chatMessages[chatId]!.add(message);
      } else {
        await loadChatMessages(chatId);
      }

      // 更新聊天列表
      await refreshChat(chatId);

      isLoading = false;
      return message;
    } catch (e) {
      errorMessage = 'Send message failed: ${e.toString()}';
      isLoading = false;
      return null;
    }
  }

  @action
  Future<void> markMessagesAsRead(String chatId) async {
    if (_authStore.currentUser == null) return;

    try {
      await _chatService.markMessagesAsRead(chatId, _authStore.currentUser!.id);

      // 更新聊天列表中的未读计数
      await refreshChat(chatId);

      // 更新消息状态
      if (chatMessages.containsKey(chatId)) {
        final messages = _chatService.getMessagesByChat(chatId);
        chatMessages[chatId] = ObservableList<MessageModel>.of(messages);
      }
    } catch (e) {
      errorMessage = 'Mark message as read failed: ${e.toString()}';
    }
  }

  @action
  Future<void> markAllAsRead() async {
    if (_authStore.currentUser == null) return;
    for (final chat in chats) {
      final count =
          chat.unreadCountPerUser[_authStore.currentUser?.id ?? ''] ?? 0;
      if (count > 0) {
        await markMessagesAsRead(chat.id);
      }
    }
    await loadUserChats();
  }

  @action
  Future<ChatModel?> createOrGetPrivateChat(String otherUserId) async {
    if (_authStore.currentUser == null) return null;

    isLoading = true;
    errorMessage = null;

    try {
      final chat = await _chatService.findOrCreatePrivateChat(
        _authStore.currentUser!.id,
        otherUserId,
      );

      // 更新聊天列表
      if (!chats.any((c) => c.id == chat.id)) {
        chats.add(chat);
      }

      isLoading = false;
      return chat;
    } catch (e) {
      errorMessage = 'Create private chat failed: ${e.toString()}';
      isLoading = false;
      return null;
    }
  }

  @action
  Future<ChatModel?> createGroupChat({
    required List<String> participantIds,
    required String groupName,
    String? groupAvatar,
  }) async {
    if (_authStore.currentUser == null) return null;

    // 确保当前用户在参与者列表中
    if (!participantIds.contains(_authStore.currentUser!.id)) {
      participantIds.add(_authStore.currentUser!.id);
    }

    isLoading = true;
    errorMessage = null;

    try {
      final chat = await _chatService.createChat(
        participantIds: participantIds,
        isGroupChat: true,
        groupName: groupName,
        groupAvatar: groupAvatar,
      );

      chats.add(chat);
      isLoading = false;
      return chat;
    } catch (e) {
      errorMessage = 'Create group chat failed: ${e.toString()}';
      isLoading = false;
      return null;
    }
  }

  @action
  Future<void> refreshChat(String chatId) async {
    // 更新聊天列表中的聊天项
    final updatedChat = _chatService.getChatById(chatId);
    if (updatedChat != null) {
      final index = chats.indexWhere((c) => c.id == chatId);
      if (index >= 0) {
        // 用replaceRange触发MobX响应式
        chats.replaceRange(index, index + 1, [updatedChat]);
      } else {
        chats.add(updatedChat);
      }
      // 重新排序
      chats.sort((a, b) => b.lastMessageTime.compareTo(a.lastMessageTime));
      // 如果是当前聊天，也更新它
      if (currentChat?.id == chatId) {
        currentChat = updatedChat;
      }
    }
  }
}
